package se.teamscape.client.view;

import net.customware.gwt.presenter.client.EventBus;
import se.teamscape.client.controller.AppController;
import se.teamscape.client.event.LoginRequestEvent;
import se.teamscape.client.presenter.LoginPresenter;

import com.google.gwt.dom.client.ButtonElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.inject.Inject;

/**
 * View that handles user login.
 * This view is a bit unique since the DOM elements are defined
 * in our TeamScape html markup. This is required for the browser
 * auto-complete feature to work.
 * 
 * Here we retrieve the form and its elements by id and sets the submit action
 * to a JSNI method that we have defined. We will post a LoginRequestEvent
 * as the result of the user clicking the submit button.
 * 
 * @author Andreas Borglin
 * 
 */
public class LoginView extends BaseView implements LoginPresenter.Display {

    // Login ids. These MUST match the ids in TeamScape.html!
    private static final String LOGINFORM_ID = "loginForm";
    private static final String LOGINBUTTON_ID = "loginSubmit";
    private static final String REMEMBERME_ID = "loginRememberMe";
    private static final String USERNAME_ID = "loginUsername";
    private static final String PASSWORD_ID = "loginPassword";

    private FlowPanel mPanel;
    private final EventBus mEventBus;

    @Inject
    public LoginView(EventBus eventBus) {
        mEventBus = eventBus;
    }

    @Override
    public void init() {

        // Get a handle to the form and set its action to our jsni method
        FormPanel form = FormPanel.wrap(Document.get().getElementById(LOGINFORM_ID), false);
        form.setAction("javascript:__gwt_login()");

        // Get the submit button for text localization
        ButtonElement submit = (ButtonElement) Document.get().getElementById(LOGINBUTTON_ID);
        submit.setInnerText(AppController.getConstants().login());

        // We have reserved a table cell for a remember me checkbox, so let's
        // add that to the cell
        TableCellElement rememberMeCell = (TableCellElement) Document.get().getElementById(REMEMBERME_ID);
        CheckBox box = new CheckBox(AppController.getConstants().rememberMe());
        rememberMeCell.appendChild(box.getElement());

        // Now, inject the jsni method for handling the form submit
        injectLoginFunction(this);

        // Add the form to the panel
        mPanel = new FlowPanel();
        mPanel.add(form);

        initWidget(mPanel);

    }

    // This is our JSNI method that will be called on form submit
    private native void injectLoginFunction(LoginView view) /*-{
        $wnd.__gwt_login = function(){
        view.@se.teamscape.client.view.LoginView::doLogin()();
        }
    }-*/;

    // This is our internal method that is called from the JSNI method
    @SuppressWarnings("unused")
    private void doLogin() {
        mEventBus.fireEvent(new LoginRequestEvent(getUsername(), getPassword()));
    }

    @Override
    public String getPassword() {
        return ((InputElement) Document.get().getElementById(PASSWORD_ID)).getValue();
    }

    @Override
    public String getUsername() {
        return ((InputElement) Document.get().getElementById(USERNAME_ID)).getValue();
    }

}
